/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.yonsei.iwb.sdt.refinement.generator;

import org.yonsei.iwb.sdt.util.SDTLog;
import org.yonsei.iwb.sdt.util.UtilFunctions;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.RDF;
import java.util.List;
import java.util.Vector;
import org.yonsei.iwb.sdt.datastructure.DecomposeCandidate;
import org.yonsei.iwb.sdt.datastructure.DecomposeCandidateSet;
import org.yonsei.iwb.sdt.datastructure.tree.BranchingType;
import org.yonsei.iwb.sdt.refinement.ConceptConstructorRefinement;
import org.yonsei.iwb.sdt.refinement.DLConstructors;
import org.yonsei.iwb.sdt.refinement.Refinement;
import org.yonsei.iwb.sdt.refinement.RefinementType;

/**
 *
 * @author JDK
 */
public class ConceptConstructorRefinementMaker extends Thread{

    private Model model;
    private Vector<Resource> instanceSet;
    private Vector<Resource> classes;
    private DecomposeCandidateSet dcs;

    public ConceptConstructorRefinementMaker(Model model, Vector<Resource> instanceSet) {
        this.model = model;
        this.instanceSet = instanceSet;
    }
    
    public ConceptConstructorRefinementMaker(DecomposeCandidateSet dcs, Model model, Vector<Resource> instanceSet, Vector<Resource> classes) {
        this.dcs = dcs;
        this.model = model;
        this.instanceSet = instanceSet;
        this.classes = classes;
    }
    
    public void decomposeCandidateOfCCR() {
        for (int i = 0; i < classes.size(); i++) {
            Resource typeclass = classes.get(i);
            decomposeCandidateGenerator(typeclass);            
        }
    }
    
    private void decomposeCandidateGenerator(Resource typeclass) {
        Vector<Refinement> refset = new Vector<Refinement>();
        Vector<Resource> cloneSet = new Vector(instanceSet);

        Refinement pref = new ConceptConstructorRefinement("", typeclass, RefinementType.TOPCONCEPTCONSTRUCTOR);
        ResIterator rt = this.model.listResourcesWithProperty(RDF.type, typeclass);
        while (rt.hasNext()) {
            Resource result = rt.nextResource();
            if (instanceSet.contains(result)) {
                pref.setInstanceSet(result);
                cloneSet.remove(result);
            }
        }
        
        if(!pref.getInstanceSet().isEmpty()){
            refset.add(pref);
            if(!cloneSet.isEmpty()){
                Refinement nref = new ConceptConstructorRefinement(DLConstructors.NEGATION, typeclass, RefinementType.TOPCONCEPTCONSTRUCTOR);
                nref.setBranchingType(BranchingType.NEGATION_TYPE);
                nref.setInstanceSet(cloneSet);
                refset.add(nref);
            }
            dcs.add(new DecomposeCandidate(refset, RefinementType.TOPCONCEPTCONSTRUCTOR));
        }
    }
        
    @Override
    public void run(){
        
    }
    
    /**
     * 다수의 클래스로 한번에 분할
     * @param v 한번에 분할되는 클래스 집합
     * @return 
     */
    public Vector<Refinement> refinementGenerator(List<Resource> v) {
        // Multi decompose case
        SDTLog.log(SDTLog.DETAIL, " Multi Decompose Candidate \n");

        Vector<Refinement> rset = new Vector<Refinement>();
        Vector<Resource> cloneSet = new Vector(instanceSet);
        Vector<Resource> subset = new Vector<Resource>();

        for (int i = 0; i < v.size(); i++) {
            Resource r = v.get(i);
            subset.add(r);
            Refinement pref = new ConceptConstructorRefinement("", r);
            
            
            ResIterator rt = this.model.listResourcesWithProperty(RDF.type, r);
            while (rt.hasNext()) {
                Resource result = rt.nextResource();                
                if (instanceSet.contains(result)) {                   
                    pref.setInstanceSet(result);
                    cloneSet.remove(result);
                }
            }
            if(!pref.getInstanceSet().isEmpty()){
                rset.add(pref);
            }
//            rset.add(pref);
        }

        if (!cloneSet.isEmpty()) {
            Refinement nref = new ConceptConstructorRefinement(subset);
            nref.setBranchingType(BranchingType.NEGATION_TYPE);
            nref.setInstanceSet(cloneSet);
            rset.add(nref);
        }

        return rset;
    }

    public Vector<Refinement> refinementGenerator(Resource r) {
        Vector<Refinement> rset = new Vector<Refinement>();
        Vector<Resource> cloneSet = new Vector(instanceSet);


        Refinement pref = new ConceptConstructorRefinement("", r);
        Refinement nref = new ConceptConstructorRefinement(DLConstructors.NEGATION, r);
        nref.setBranchingType(BranchingType.NEGATION_TYPE);

//        StmtIterator st = this.model.listStatements(null, RDF.type, r);
        ResIterator rt = this.model.listResourcesWithProperty(RDF.type, r);        
        while (rt.hasNext()) {            
            Resource result = rt.nextResource();            
            if (instanceSet.contains(result)) {
                pref.setInstanceSet(result);
                cloneSet.remove(result);
            }
        }

        nref.setInstanceSet(cloneSet);
        
        if(!cloneSet.isEmpty()&& !pref.getInstanceSet().isEmpty()){
            rset.add(pref);
            rset.add(nref);
        }else{
            return null;
        }
        
        return rset;
    }
}
